<?php
declare(strict_types=1);

namespace WebApp\lib\db;

use SplQueue;
use Throwable;

/**
 * Class RedisUtil
 * @package server\lib
 */
class Pool implements IPool
{
    /**
     * @var SplQueue
     */
    protected $pool;

    /**
     * @var IDriver
     */
    private $driver;

    /**
     * plugin_version constructor.
     * @param IDriver $driver
     */
    public function __construct(IDriver $driver)
    {
        $this->pool = new SplQueue;
        $this->driver = $driver;
    }

    /**
     * @param callable $func
     * @return mixed
     */
    public function exec(callable $func) {
        $res = null;
        $i = $this->driver->getTryCount();

        while ($i > 0) {
            if (!count($this->pool)) {
                $conn = $this->driver->getCon();
            } else {
                $conn = $this->pool->shift();
            }
            try {
                $res = $func($conn);
            } catch (Throwable $e) {
                $this->driver->catchErr($conn, $e);
            }
            if ($conn) {
                $this->pool->push($conn);
            }
            if ($res === null) {
                $i--;
                continue;
            } else {
                break;
            }
        }
        return $res;
    }
}
